/*  trimath.h - balanced ternary math with arbitrary precision.

    Part of nedoPC SDK (software development kit for simple devices)

    Copyright (C) 2011, Alexander A. Shabarshin <ashabarshin@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef __TRIMATH_H
#define __TRIMATH_H

typedef struct _trinum
{
 char *s; /* string representation of the number */
 char *e; /* optional string representation of exponent */
 int ein; /* value of exponent (0 for integers) */
 int len; /* length of ternary number in trits */
 int flg; /* flags (see below) */
}trinum;

#define TRINUM_FLAG_FROZEN   1 /* frozen sizes */
#define TRINUM_FLAG_FRACTION 2 /* ternary number is fraction */

#define TRINUM_PRINT(S,T) printf("%s %s %s\n",S,\
                                  (T&&T->s)?T->s:"O",\
                                  (T&&T->e)?T->e:" ")

#define TRINUM_PRINTD(S,T) printf("%s %s %s (%i) len=%i flg=0x%2.2X\n",S,\
                                  (T&&T->s)?T->s:"O",\
                                  (T&&T->e)?T->e:"O",\
                                  T?T->ein:0,T?T->len:0,T?T->flg:0)

#ifdef __cplusplus
extern "C" {
#endif

trinum* trinum_new(void);
trinum* trinum_new_str(char *s);
trinum* trinum_new_int(int i);
trinum* trinum_new_real(double d);
trinum* trinum_new_reale(double d, double err);
trinum* trinum_new_exponent(int i, int e);
trinum* trinum_new_copy(trinum *a);
void trinum_free(trinum *t);
int trinum_get_flag(trinum *t, int f);
int trinum_set_flag(trinum *t, int f);
int trinum_clr_flag(trinum *t, int f);
int trinum_is_int(trinum *t);
int trinum_get_int(trinum *t);
double trinum_get_real(trinum *t);

#ifdef __cplusplus
}
#endif

#endif
